﻿using Infrastructure.Config.Core.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Authorization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;

namespace Shared.Service.Authorizations.Authorization
{
    public class CustomPermissionRequirementHandler : PermissionRequirementHandler
    {


        private readonly IPermissionChecker _permissionChecker;
        protected ICurrentPrincipalAccessor PrincipalAccessor { get; }

        private readonly ILogger<CustomPermissionRequirementHandler> _logger;

        public CustomPermissionRequirementHandler(IPermissionChecker permissionChecker,
            ICurrentPrincipalAccessor principalAccessor, ILogger<CustomPermissionRequirementHandler> logger) :
            base(permissionChecker)
        {
            _permissionChecker = permissionChecker;

            PrincipalAccessor = principalAccessor;
            _logger = logger;
        }

        protected override async Task HandleRequirementAsync(
            AuthorizationHandlerContext context,
            PermissionRequirement requirement)
        {

            // 先判断是否认证过
            if (!(context.User?.Identity?.IsAuthenticated ?? false))
            {
                context.Fail();
                return;
            }


            StringBuilder sb = new StringBuilder();
            // 如果网关没有填写 策略则 自己模块调用

            //sb.Append($" UserPolicy.PermissionName:{UserPolicy.PermissionName} 对比 requirement.PermissionName:{requirement.PermissionName}  ");

            //// 网关内和 配置 的 相同
            //if (UserPolicy.PermissionName == requirement.PermissionName)
            //{
            //    context.Succeed(requirement);
            //    return;
            //}

            //// 网关内的 策略和接口的策略名不同
            //if (!requirement.PermissionName.IsNullOrWhiteSpace() && UserPolicy.PermissionName != requirement.PermissionName)
            //{
            //    // 如果在配置的范围内 直接返回true
            //    sb.Append($"   PolicyDefinition.GetOrDefault(requirement.PermissionName)?.GetPermissionNames()?.Contains(UserPolicy.PermissionName) 结果:{PolicyDefinition.GetOrDefault(requirement.PermissionName)?.GetPermissionNames()?.Contains(UserPolicy.PermissionName)}     ");
            //    if (PolicyDefinition.GetOrDefault(requirement.PermissionName)?.GetPermissionNames()?.Contains(UserPolicy.PermissionName) ?? false)
            //    {
            //        context.Succeed(requirement);
            //        return;
            //    }
            //}
            _logger.LogError(sb.ToString());
            throw new UserFriendlyException("未授权的请求！");



            if (await _permissionChecker.IsGrantedAsync(context.User, requirement.PermissionName))
            {
                SetUserPermissionName(requirement.PermissionName);
                context.Succeed(requirement); //  TODO: 需要调研
            }
            else
            {
                sb.Append($"requirement.PermissionName  {requirement.PermissionName}");
                var claims = context.User.Claims.Select(a => a.Type + ":" + a.Value).ToList();
                sb.Append(string.Join(" , ", claims));
                _logger.LogError(sb.ToString());
                throw new UserFriendlyException("未授权的请求！");
            }
        }

        private void SetUserPermissionName(string name)
        {
            PrincipalAccessor?.Principal?.AddIdentity(new ClaimsIdentity(new[]
            {
                new Claim(ClaimConsts.UserPermissionTypeClaim.Type, name)
            }, "UserPermission"));
        }
    }
}
